/*****************************************************************************/
/*                                                                           */
/*    Domino Operation System Driver Module                                  */
/*                                                                           */
/*    Copyright (C) 2011 Laszlo Arvai                                        */
/*                                                                           */
/*    ------------------------------------------------------------------     */
/*    I2C Driver for PIC24 series                                            */
/*****************************************************************************/

///////////////////////////////////////////////////////////////////////////////
// Includes
#define USE_AND_OR
#include <i2c.h>
#include <drvI2C.h>
#include "drvIOConfig.h"

/*****************************************************************************/
/* I2C 1 Functions                                                           */
/*****************************************************************************/

#if defined(drvI2C1_CON)

///////////////////////////////////////////////////////////////////////////////
// Initialize I2C driver
void drvI2C1Init(void)
{
	I2C1CON = drvI2C1_CON;
	I2C1BRG = (sysCLOCK_FREQUENCY/2)/(2*drvI2C1_BAUD_RATE)-1;
}

///////////////////////////////////////////////////////////////////////////////
// Issue start condition (true is start was acknowledged)
dosBool drvI2C1Start(drvI2CRWMode in_mode, dosByte in_address)
{
	// be sure bus is idle
	drvI2C1Wait();
	
	// start condition
	I2C1CONbits.SEN = 1;   			// Initiate Start on SDA and SCL pins */
	drvI2C1Wait();							// Wait till Start sequence is completed

	return drvI2C1SendAddress(in_mode, in_address);
}

///////////////////////////////////////////////////////////////////////////////
// Sends Restart condition
dosBool drvI2C1Restart(drvI2CRWMode in_mode, dosByte in_address)
{
	I2C1CONbits.RSEN = 1;   		// Initiate restart on SDA and SCL pins
  while(I2C1CONbits.RSEN );   // Wait till Restart sequence is completed
		
	return drvI2C1SendAddress(in_mode, in_address);
}

///////////////////////////////////////////////////////////////////////////////
// Sends device address and waits for ack
dosBool drvI2C1SendAddress(drvI2CRWMode in_mode, dosByte in_address)
{
	// address and mode
	I2C1TRN = (in_address << 1) | ((dosByte)in_mode);
	drvI2C1Wait();

	return (I2C1STATbits.ACKSTAT == 0);
}

///////////////////////////////////////////////////////////////////////////////
// Issue stop condition
void drvI2C1Stop(void)
{
   I2C1CONbits.PEN = 1;			// Initiate Stop on SDA and SCL pins
   drvI2C1Wait();						// Wait till stop sequence is completed
}

///////////////////////////////////////////////////////////////////////////////
// Sends data byte
dosByte drvI2C1WriteByte(dosByte in_data)
{
	I2C1TRN = in_data;
	drvI2C1Wait();

	return (I2C1STATbits.ACKSTAT == 0);
}

///////////////////////////////////////////////////////////////////////////////
// Reads one byte from the bus
dosByte drvI2C1ReadByte(drvI2CACK in_ack)
{
	dosByte data;
	
	// read byte
	I2C1CONbits.RCEN = 1;
	drvI2C1Wait();
  I2C1STATbits.I2COV = 0;
  data = I2C1RCV;
	
	// generate ACK/NACK
	if(in_ack == drvI2C_ACK)
	{
		I2C1CONbits.ACKDT = 0;
		I2C1CONbits.ACKEN = 1;
	}
	else
	{
		I2C1CONbits.ACKDT = 1;
		I2C1CONbits.ACKEN = 1;
	}
  drvI2C1Wait();					   // Wait till ACK/NACK sequence is over
  
	return data;
}

///////////////////////////////////////////////////////////////////////////////
// True if I2C bus is busy
dosBool drvI2C1IsBusy(void)
{
	return (I2C1CONbits.SEN || I2C1CONbits.RSEN || I2C1CONbits.PEN || I2C1CONbits.RCEN || I2C1CONbits.ACKEN || I2C1STATbits.TRSTAT); 
}

///////////////////////////////////////////////////////////////////////////////
// Waits while I2C bus is busy
void drvI2C1Wait(void)
{
	while(drvI2C1IsBusy());
}

#endif

/*****************************************************************************/
/* I2C 2 Functions                                                           */
/*****************************************************************************/
#if defined(drvI2C2_CON)
#endif
